﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "NewGbmpDocumentInitializer.h"

#include "LevelNameManager.h"
#include "GridNameManager.h"
#include "GbmpModelViewUtil.h"
#include "IBuilding.h"
#include "ILevelType.h"
#include "ILevel.h"
#include "IGbmpPlanView.h"
#include "IGbmpElevationView.h"
#include "IGbmp3DView.h"

// 平台头文件
#include "IDocumentManager.h"
#include "IDocument.h"
#include "IUserTransaction.h"
#include "GbmpFileSystem.h"
#include "IFillPatternData.h"
#include "IFillPattern.h"
#include "ILineTypeData.h"
#include "ILineTypeNew.h"
#include "IRevisionCloudStyleManager.h"
#include "IElementLocator.h" 

#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

using namespace gcmp;

namespace
{
    const wchar_t* g_hatchPatterns[] =
    {
        L"SOLID",
        L"ANSI31",
        L"AR-RROOF",
        L"AR-SAND",
        L"CROSS"
    };
    std::vector<std::wstring> GetSupportedHatchPatterns()
    {
        return std::vector<std::wstring>(g_hatchPatterns, g_hatchPatterns + sizeof(g_hatchPatterns) / sizeof(const wchar_t *));
    }
}

NewGbmpProjectDocumentInitializer::NewGbmpProjectDocumentInitializer()
{
}

bool NewGbmpProjectDocumentInitializer::InitializeDocument(IDocument* pDocument)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pDocument, L"pDocument为空。",L"GDMPLab",L"2024-03-30");

    OwnerPtr<IUserTransaction> opUt = IUserTransaction::Create(pDocument, GBMP_TR(L"初始化项目文档相关数据"));
    DBG_WARN_AND_RETURN_FALSE_UNLESS(opUt != nullptr, L"事务创建不成功",L"GDMPLab",L"2024-03-30");

    // 创建罗盘
    IElementLocator *pLocator = IElementLocator::Create(pDocument);

    // 标高名称管理器初始化
    LevelNameManager::Create(pDocument);

    // 轴网名称管理器初始化
    GridNameManager::Create(pDocument);

    // 新建单体
    IBuilding* pBuilding = IBuilding::Create(pDocument, L"单体A");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pBuilding != nullptr, L"IBuilding创建失败",L"GDMPLab",L"2024-03-30");
    ElementId buildingId = pBuilding->GetOwnerElement()->GetElementId();

    // 新标高类型
    ILevelType* pLevelType = ILevelType::Create(pDocument, GBMP_TR(L"标准标高"));
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pLevelType, L"标准标高创建失败",L"GDMPLab",L"2024-03-30");
    ElementId levelTypeId = pLevelType->GetOwnerElement()->GetElementId();

    // 新标高1
    ILevel* pLevel1 = ILevel::Create(pDocument, levelTypeId, GBMP_TR(L"楼层 1"),
        Vector3d(-20000.0, 0, 0),
        Vector3d(20000.0, 0, 0),
        Vector3d::UnitY,
        buildingId
    );
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pLevel1, L"楼层创建失败",L"GDMPLab",L"2024-03-30");

    // 新标高2
    ILevel* pLevel2 = ILevel::Create(pDocument, levelTypeId, GBMP_TR(L"楼层 2"),
        Vector3d(-20000.0, 0, 3000.0),
        Vector3d(20000.0, 0, 3000.0),
        Vector3d::UnitY,
        buildingId
    );
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pLevel2, L"楼层创建失败",L"GDMPLab",L"2024-03-30");

    // 平面视图
    {
        GbmpPlanViewInput input;
        input.Document = pDocument;
        input.Name = pLevel1->GetName();
        input.Level = pLevel1;
        IGbmpPlanView* pPlanView = IGbmpPlanView::Create(input);
        DBG_WARN_AND_RETURN_FALSE_UNLESS(pPlanView, L"pPlanView为空",L"GDMPLab",L"2024-03-30");
    }
    {
        GbmpPlanViewInput input;
        input.Document = pDocument;
        input.Name = pLevel2->GetName();
        input.Level = pLevel2;
        IGbmpPlanView* pPlanView = IGbmpPlanView::Create(input);
        DBG_WARN_AND_RETURN_FALSE_UNLESS(pPlanView, L"pPlanView为空",L"GDMPLab",L"2024-03-30");
    }

    // 立面视图
    IGbmpElevationView* pEastElevationView = GbmpModelViewUtil::CreateEastElevationView(pDocument);
    IGbmpElevationView* pWestElevationView = GbmpModelViewUtil::CreateWestElevationView(pDocument);
    IGbmpElevationView* pSouthElevationView = GbmpModelViewUtil::CreateSouthElevationView(pDocument);
    IGbmpElevationView* pNorthElevationView = GbmpModelViewUtil::CreateNorthElevationView(pDocument);

    // 三维视图
    {
        Gbmp3DViewInput input;
        input.Document = pDocument;
        input.Name = GBMP_TR(L"三维");
        input.Level = pLevel1;
        IGbmp3DView* p3DView = IGbmp3DView::Create(input);
        DBG_WARN_AND_RETURN_FALSE_UNLESS(p3DView, L"p3DView为空",L"GDMPLab",L"2024-03-30");
    }

    LoadHatchPatterns(pDocument);
    LoadLineTypes(pDocument);      // 作为GBMP项目环境加载

    IRevisionCloudStyleManager::Create(pDocument);

    // 提交事务并重置历史
    opUt->CommitAndResetHistory();

    // 忽略文档初始化引起的改动
    pDocument->SetIsChangedAfterPreviousSave(false);

    return true;
}

void gcmp::NewGbmpProjectDocumentInitializer::LoadHatchPatterns(IDocument* pDocument)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(pDocument, L"pDocument为空。",L"GDMPLab",L"2024-03-30");

    //std::wstring resourcePath = FileSystem::GetSdkDirPath();
    std::wstring resourcePath = FileSystem::GetExeDirPath();
    std::wstring patchFilePath = resourcePath + L"sdk\\PublicResourceFiles\\GcmpHatchPatterns.pat";
    std::vector<OwnerPtr<IFillPatternData>> hatchPatterns = IFillPatternData::Create(patchFilePath);
    std::vector<std::wstring> supportedHatchPatterns = GetSupportedHatchPatterns();
    for (auto& iter: hatchPatterns)
    {
        DBG_WARN_AND_CONTINUE_UNLESS(iter, L"iter为空。",L"GDMPLab",L"2024-03-30");
        std::wstring name = iter->GetName();

        auto it = std::find(supportedHatchPatterns.begin(), supportedHatchPatterns.end(), name);
        if (it != supportedHatchPatterns.end())
        {
            iter->SetScale(25.0);
            if (name == L"AR-RROOF")
                iter->SetRotateAngle(-45.0f);
            else if (name == L"SOLID")
                iter->SetIsSolid(true);
            else;
            IFillPattern* pelement = IFillPattern::Create(pDocument, TransferOwnership(iter), true);
        }
    }
}

void gcmp::NewGbmpProjectDocumentInitializer::LoadLineTypes(IDocument* pDocument)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(pDocument, L"pDocument为空。",L"GDMPLab",L"2024-03-30");
    std::wstring resourcePath = FileSystem::GetExeDirPath();
    std::wstring lineTypeFilePath = resourcePath + L"acad.lin";
    std::vector<OwnerPtr<ILineTypeData>> lineTypes = ILineTypeData::Create(lineTypeFilePath);
    for (auto& it : lineTypes)
        ILineTypeNew* pelement = ILineTypeNew::Create(pDocument, TransferOwnership(it), true);
}
